/* Copyright 2014 Jan Wolter */

#include "stack.h"

void riffle(Stack *old, Stack *new, int a)
{
    /* Size of input deck */
    int n= old->n;

    /* Make sure output deck is big enough */
    expandStack(new,n,0);
    new->n= n;

    if (a <= 0 || n <= 0) return;

    int *firstPos= (int *)malloc(a*sizeof(int));
    int *nextPos= (int *)malloc(n*sizeof(int));

    for (int i= 0; i < a; i++)
	firstPos[i]= -1;

    for (int i= n-1; i >= 0; i--)
    {
	int pack= randint(a);
	nextPos[i]= firstPos[pack];
	firstPos[pack]= i;
    }

    int j= 0;
    for (int pack= 0; pack < a; pack++)
	for (int i= firstPos[pack]; i >= 0; i= nextPos[i])
	    new->c[i]= old->c[j++];

    free(firstPos);
    free(nextPos);
}

void overhand(Stack *old, Stack *new, int oneoverp, int n)
{
    Stack *tmp;
    int size= old->n;
    expandStack(new, size, 0);
    new->n= size;

    Stack *from= old;
    Stack *to= new;

    for (int i= 0; i < n; i++)
    {
	int s= 0;	/* First card of the current batch */
	for (int j= 1; j <= size; j++)
	{
	    if (j == size || randint(oneoverp) == 0)
	    {
		/*printf("BATCH %d-%d\n",s,j-1);*/
		/* End of a batch - copy the cards */
		for (int k= s; k < j; k++)
		    to->c[size - j + k - s]= from->c[k];
		/* Start a new batch */
		s= j;
	    }
	}
	/*printStack(stdout, "X", to);*/
	tmp= to; to= from; from= tmp;
    }

    /* If deck ended up in the wrong array, copy it over */
    if (from == old)
    {
	for (int i= 0; i < size; i++)
	    new->c[i]= old->c[i];
    }
    /*printStack(stdout, "New", new);*/
}

void cutdeck(Stack *old, Stack *new)
{
    int i;
    int n= old->n;

    /* Make sure output deck is big enough */
    expandStack(new,n,0);
    new->n= n;

    /* if (n <= 1) return; */

    /* Generate a normally distributed random number the dumb way */
    int k= 0;
    for (i= 0; i < n; i++)
	k+= randint(2);

    for (i= 0; i < k; i++)
	new->c[i+n-k]= old->c[i];
    for (; i < n; i++)
	new->c[i-k]= old->c[i];
}
